package com.evil.application.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.evil.account.api.RemoteUserEnterpriseService;
import com.evil.account.api.RemoteUserService;
import com.evil.application.api.RemoteApplicationButtonService;
import com.evil.application.mapper.ApplicationButtonMapper;
import com.evil.application.mapper.ApplicationInfoMapper;
import com.evil.application.pojo.dto.button.*;
import com.evil.application.pojo.entity.ApplicationButton;
import com.evil.application.pojo.entity.ApplicationInfo;
import com.evil.application.service.ApplicationButtonService;
import com.evil.application.service.ApplicationJudgeService;
import com.evil.application.service.ApplicationPermissionService;
import com.evil.application.service.ApplicationRobotRuleService;
import com.evil.application.util.ApplicationUtil;
import com.evil.common.account.dto.user.UserBaseRespDTO;
import com.evil.common.account.util.LoginUtil;
import com.evil.common.application.dto.button.ButtonSourceDTO;
import com.evil.common.application.dto.judge.CopyJudgeReqDTO;
import com.evil.common.application.dto.judge.JudgeOr;
import com.evil.common.application.dto.judge.JudgeSourceDTO;
import com.evil.common.application.dto.judge.JudgesDTO;
import com.evil.common.application.dto.permission.app.AppPermissionDTO;
import com.evil.common.application.dto.permission.app.AppPermissionSourceDTO;
import com.evil.common.application.dto.permission.app.CopyAppPermissionReqDTO;
import com.evil.common.application.dto.permission.app.ModifyAppPermissionReqDTO;
import com.evil.common.application.dto.robot.RobotRuleDTO;
import com.evil.common.application.dto.robot.rule.CopyRobotRuleReqDTO;
import com.evil.common.application.dto.robot.rule.RobotRuleSourceDTO;
import com.evil.common.application.dto.robot.rule.RobotRulesDTO;
import com.evil.common.application.enums.ApplicationSourceTypeEnum;
import com.evil.common.application.enums.ApplicationVersionEnum;
import com.evil.common.application.enums.button.ButtonSourceTypeEnum;
import com.evil.common.application.enums.button.TriggerActionEnum;
import com.evil.common.application.enums.judge.JudgeSourceTypeEnum;
import com.evil.common.application.enums.permission.PermissionStatusEnum;
import com.evil.common.application.enums.robot.RobotRuleSourceTypeEnum;
import com.evil.common.core.dto.FindByIdsReqDTO;
import com.evil.common.core.enums.RCodeEnum;
import com.evil.common.core.enums.SwitchEnum;
import com.evil.common.core.exception.BusinessException;
import com.evil.common.core.util.StreamUtil;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * 自定义按钮表
 *
 * @author liyang
 * @date 2022-08-08 00:00
 */
@Slf4j
@RestController
@AllArgsConstructor
public class ApplicationButtonServiceImpl extends ServiceImpl<ApplicationButtonMapper, ApplicationButton> implements ApplicationButtonService, RemoteApplicationButtonService {

    private final static ButtonSourceTypeEnum APP_BUTTON = ButtonSourceTypeEnum.APPLICATION_BUTTON;
    private final static RobotRuleSourceTypeEnum ROBOT_RULE_TYPE = RobotRuleSourceTypeEnum.CUSTOM_BUTTON_RULE;
    private final static JudgeSourceTypeEnum JUDGE_TYPE = JudgeSourceTypeEnum.APPLICATION_BUTTON_FILTER_CONDITION;
    private final static JudgeSourceTypeEnum TRIGGER_CONDITION = JudgeSourceTypeEnum.APPLICATION_BUTTON_TRIGGER_CONDITION;
    private final static ApplicationSourceTypeEnum APP_PERMISSION_TYPE = ApplicationSourceTypeEnum.APPLICATION_BUTTON;

    private final LoginUtil loginUtil;

    private final ApplicationInfoMapper applicationInfoMapper;

    private final ApplicationPermissionService applicationPermissionService;

    private final ApplicationJudgeService applicationJudgeService;

    private final ApplicationRobotRuleService applicationRobotRuleService;

    private final RemoteUserService remoteUserService;

    private final RemoteUserEnterpriseService remoteUserEnterpriseService;

    private final ApplicationLogServiceImpl logService;

    /**
     * 按钮列表
     *
     * @param buttonSourceDTO buttonSourceDTO
     */
    @Override
    public List<ButtonInfoRespDTO> findBySource(ButtonSourceDTO buttonSourceDTO) {
        return this.perfectButtonInfo(this.baseMapper.findBySource(buttonSourceDTO));
    }

    /**
     * 添加应用按钮
     *
     * @param addButtonReqDTO addButtonReqDTO
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void addButton(AddButtonReqDTO addButtonReqDTO) {
        String applicationKey = addButtonReqDTO.getApplicationKey();
        String buttonKey = addButtonReqDTO.getButtonKey();
        if (StringUtils.isNotBlank(buttonKey)) {
            buttonKey = buttonKey.trim();
            if (buttonKey.length() < 8 || buttonKey.length() > 32) {
                throw new BusinessException(RCodeEnum.ERROR_PARAMETER, "应用key错误");
            }
        }
        Long paramEnterpriseId = loginUtil.getParamEnterpriseId(addButtonReqDTO.getEnterpriseId());

        addButtonReqDTO.check();

        // 检查企业管理员
        remoteUserEnterpriseService.checkEnterpriseManager(loginUtil.getLoginUserEnterprise());

        ApplicationInfo applicationInfo = applicationInfoMapper.findByKey(applicationKey);
        // 检查企业
        loginUtil.checkEnterpriseId(applicationInfo.getEnterpriseId());

        if (StringUtils.isNotBlank(buttonKey)) {
            if (this.baseMapper.isExistByKeyAndVersion(buttonKey, ApplicationVersionEnum.DESIGN_VERSION.getId()).isPresent()) {
                throw new BusinessException(RCodeEnum.ERROR_PARAMETER, "按钮key已存在");
            }
        } else {
            // 生成key
            buttonKey = ApplicationUtil.generateKey(key -> this.baseMapper.isExistByKeyAndVersion(key, ApplicationVersionEnum.DESIGN_VERSION.getId()).isPresent());
        }

        ApplicationButton applicationButton = new ApplicationButton();
        applicationButton.setEnterpriseId(paramEnterpriseId);
        applicationButton.setButtonKey(buttonKey);
        applicationButton.setSourceId(applicationInfo.getApplicationId());
        applicationButton.setSourceType(ButtonSourceTypeEnum.APPLICATION_BUTTON.getId());
        applicationButton.setVersion(ApplicationVersionEnum.DESIGN_VERSION.getId());
        this.savaButton(applicationButton, addButtonReqDTO);
    }

    /**
     * 编辑应用按钮
     *
     * @param modifyButtonReqDTO modifyButtonReqDTO
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void modifyButton(ModifyButtonReqDTO modifyButtonReqDTO) {
        modifyButtonReqDTO.check();

        // 校验权限
        remoteUserEnterpriseService.checkEnterpriseManager(loginUtil.getLoginUserEnterprise());

        // 查找数据
        ApplicationButton applicationButton = this.baseMapper.findById(modifyButtonReqDTO.getButtonId());
        // 检查企业
        loginUtil.checkEnterpriseId(applicationButton.getEnterpriseId());

        // 如果是发布版，不允许编辑
        if (applicationButton.getVersion() == ApplicationVersionEnum.RELEASE_VERSION.getId()) {
            throw new BusinessException(RCodeEnum.ERROR_PARAMETER, "不允许编辑发布版按钮");
        }
        this.savaButton(applicationButton, modifyButtonReqDTO);
    }

    /**
     * 复制应用按钮
     *
     * @param buttonId buttonId
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void copyButton(Long buttonId) {
        // 检查是否是管理员
        remoteUserEnterpriseService.checkEnterpriseManager(loginUtil.getLoginUserEnterprise());

        ApplicationButton button = this.baseMapper.findById(buttonId);
        // 检查企业
        loginUtil.checkEnterpriseId(button.getEnterpriseId());

        // 复制应用按钮
        ButtonSourceDTO targetSource = new ButtonSourceDTO(button.getSourceType(), button.getSourceId(), button.getVersion());
        this.copyButton(button, targetSource, new HashMap<>(), null, false);
    }

    /**
     * 删除应用按钮
     *
     * @param delButtonReqDTO delButtonReqDTO
     */
    @Override
    public void delButton(DelButtonReqDTO delButtonReqDTO) {
        // 校验权限
        remoteUserEnterpriseService.checkEnterpriseManager(loginUtil.getLoginUserEnterprise());

        // 查找数据
        ApplicationButton applicationButton = this.baseMapper.findById(delButtonReqDTO.getButtonId());
        // 检查企业
        loginUtil.checkEnterpriseId(applicationButton.getEnterpriseId());

        // 如果是发布版，不允许编辑
        if (applicationButton.getVersion() == ApplicationVersionEnum.RELEASE_VERSION.getId()) {
            throw new BusinessException(RCodeEnum.ERROR_PARAMETER, "不允许编辑发布版按钮");
        }

        applicationButton.setIsDeleted(SwitchEnum.YES.getId());
        logService.saveAndCheck(this.baseMapper, ApplicationButton::getButtonId, applicationButton);
    }

    /**
     * 按钮列表[管理员]
     *
     * @param buttonListReqDTO buttonListReqDTO
     * @return List
     */
    @Override
    public List<ButtonInfoRespDTO> buttonList(ButtonListReqDTO buttonListReqDTO) {
        String applicationKey = buttonListReqDTO.getApplicationKey();
        Integer version = buttonListReqDTO.getVersion();
        // 校验权限
        remoteUserEnterpriseService.checkEnterpriseManager(loginUtil.getLoginUserEnterprise());

        ApplicationInfo applicationInfo = applicationInfoMapper.findByKey(applicationKey);
        // 检查企业
        loginUtil.checkEnterpriseId(applicationInfo.getEnterpriseId());

        return this.perfectButtonInfo(this.baseMapper.findBySource(new ButtonSourceDTO(APP_BUTTON, applicationInfo.getApplicationId(), version)));
    }

    /**
     * 根据按钮keys获取按钮列表
     *
     * @param buttonListForKeysReqDTO buttonListForKeysReqDTO
     * @return List
     */
    @Override
    public List<ButtonInfoRespDTO> buttonListForKeys(ButtonListForKeysReqDTO buttonListForKeysReqDTO) {
        List<ApplicationButton> buttons = this.baseMapper
                .findByKeys(buttonListForKeysReqDTO.getButtonKeys(), ApplicationVersionEnum.RELEASE_VERSION.getId());

        // 检查企业
        buttons.forEach(b -> loginUtil.checkEnterpriseId(b.getEnterpriseId()));
        return this.perfectButtonInfo(buttons);
    }

    /**
     * 按钮基础信息列表
     *
     * @param buttonListReqDTO buttonListReqDTO
     * @return List
     */
    @Override
    public List<ButtonBaseDTO> bases(ButtonListReqDTO buttonListReqDTO) {
        ApplicationInfo applicationInfo = applicationInfoMapper.findByKey(buttonListReqDTO.getApplicationKey());
        // 检查企业
        loginUtil.checkEnterpriseId(applicationInfo.getEnterpriseId());

        ButtonSourceDTO source = new ButtonSourceDTO(ButtonSourceTypeEnum.APPLICATION_BUTTON, applicationInfo.getApplicationId(), buttonListReqDTO.getVersion());
        source.setInTable(buttonListReqDTO.getInTable());
        source.setInDetail(buttonListReqDTO.getInDetail());
        return StreamUtil.transListT(this.baseMapper.findBySource(source), ButtonBaseDTO::new);
    }

    /**
     * 按钮详情
     *
     * @param buttonInfoReqDTO buttonInfoReqDTO
     * @return ButtonRuleRespDTO
     */
    @Override
    public ButtonInfoRespDTO buttonInfo(ButtonInfoReqDTO buttonInfoReqDTO) {
        // 校验权限
        remoteUserEnterpriseService.checkEnterpriseManager(loginUtil.getLoginUserEnterprise());

        // 查找数据
        ApplicationButton button = this.baseMapper.findById(buttonInfoReqDTO.getButtonId());
        // 检查企业
        loginUtil.checkEnterpriseId(button.getEnterpriseId());

        Long buttonId = button.getButtonId();
        Long creatorId = button.getCreatorId();

        // 按钮规则
        List<RobotRuleDTO> robotRules = applicationRobotRuleService.findBySource(new RobotRuleSourceDTO(ROBOT_RULE_TYPE, buttonId));
        // 按钮筛选条件
        List<JudgeOr> judgeOrs = applicationJudgeService.findDTOBySource(new JudgeSourceDTO(JUDGE_TYPE, buttonId));
        // 按钮权限
        List<AppPermissionDTO> permissions = applicationPermissionService.findDTOBySource(new AppPermissionSourceDTO(APP_PERMISSION_TYPE, buttonId));
        // 创建人
        UserBaseRespDTO creator = remoteUserService.findBaseById(creatorId);

        ButtonInfoRespDTO buttonInfoRespDTO = BeanUtil.copyProperties(button, ButtonInfoRespDTO.class);
        // 按钮规则
        buttonInfoRespDTO.setRobotRules(robotRules);
        // 按钮筛选条件
        buttonInfoRespDTO.setJudgeOrs(judgeOrs);
        // 按钮权限
        buttonInfoRespDTO.setPermissions(permissions);
        buttonInfoRespDTO.setCreator(creator);
        return buttonInfoRespDTO;
    }

    /**
     * 保存按钮
     *
     * @param modifyButtonsReqDTO modifyButtonsReqDTO
     */
    @Override
    public void saveButtons(ModifyButtonsReqDTO modifyButtonsReqDTO) {
        List<ButtonRespDTO> buttons = modifyButtonsReqDTO.getButtons();
        ButtonSourceDTO source = modifyButtonsReqDTO.getSource();
        Long paramEnterpriseId = loginUtil.getParamEnterpriseId(modifyButtonsReqDTO.getEnterpriseId());

        // 检查参数
        buttons.forEach(ButtonRespDTO::check);
        // 检查企业
        loginUtil.checkEnterpriseId(paramEnterpriseId);

        Map<Long, ButtonRespDTO> buttonBaseMap = StreamUtil.toMapFK(buttons, e -> Objects.nonNull(e.getButtonId()), ButtonRespDTO::getButtonId);

        List<ApplicationButton> buttonList = this.baseMapper.findBySource(source);
        Map<Long, ApplicationButton> buttonMap = StreamUtil.toMapK(buttonList, ApplicationButton::getButtonId);

        // 新增编辑
        buttons.forEach(b -> {
            ApplicationButton button;
            if (Objects.nonNull(b.getButtonId())) {
                if (!buttonMap.containsKey(b.getButtonId())) {
                    throw new BusinessException(RCodeEnum.APPLICATION_BUTTON_NOT_EXIST);
                }
                button = buttonMap.get(b.getButtonId());
            } else {
                button = new ApplicationButton();
                button.setSourceId(source.getSourceId());
                button.setSourceType(source.getSourceType());
                button.setEnterpriseId(paramEnterpriseId);
                button.setVersion(source.getVersion());
            }
            this.savaButton(button, b);
        });

        List<ApplicationButton> deletedList = StreamUtil.peekF(buttonList,
                e -> !buttonBaseMap.containsKey(e.getButtonId()), e -> e.setIsDeleted(SwitchEnum.YES.getId()));
        logService.saveAndCheck(this.baseMapper, ApplicationButton::getButtonId, deletedList);
    }

    /**
     * 发布自定义按钮
     *
     * @param applicationInfo applicationInfo
     * @param controlIdMap    controlIdMap
     */
    @Override
    public void publishButton(ApplicationInfo applicationInfo, Map<Long, Long> controlIdMap) {
        this.replaceButton(applicationInfo, controlIdMap, true);
    }

    /**
     * 还原自定义按钮
     *
     * @param applicationInfo applicationInfo
     * @param controlIdMap    controlIdMap
     */
    @Override
    public void restoreButton(ApplicationInfo applicationInfo, Map<Long, Long> controlIdMap) {
        this.replaceButton(applicationInfo, controlIdMap, false);
    }

    /**
     * 复制按钮
     *
     * @param copyButtonReqDTO copyButtonReqDTO
     */
    @Override
    public void copyButton(CopyButtonReqDTO copyButtonReqDTO) {
        ButtonSourceDTO source = copyButtonReqDTO.getSource();
        ButtonSourceDTO target = copyButtonReqDTO.getTarget();
        Map<Long, Long> controlIdMap = copyButtonReqDTO.getControlIdMap();
        Boolean updateSource = copyButtonReqDTO.getUpdateSource();

        List<ApplicationButton> sourceList = this.baseMapper.findBySource(source);
        List<ApplicationButton> targetList = this.baseMapper.findBySource(target);

        // 过滤源按钮id为默认值的
        Predicate<ApplicationButton> filter = e -> !ApplicationUtil.DEFAULT_SOURCE_BUTTON_ID.equals(e.getSourceButtonId());
        Map<Long, ApplicationButton> sourceButtonMap = StreamUtil.toMapFK(sourceList, filter, ApplicationButton::getSourceButtonId);
        Map<Long, ApplicationButton> targetButtonMap = StreamUtil.toMapFK(targetList, filter, ApplicationButton::getSourceButtonId);

        // 新增编辑
        sourceList.forEach(button -> this.copyButton(button, target, targetButtonMap, controlIdMap, updateSource));

        // 删除无效
        List<ApplicationButton> deletedList = targetList.stream()
                .filter(e -> !sourceButtonMap.containsKey(e.getButtonId()))
                .peek(e -> e.setIsDeleted(SwitchEnum.YES.getId()))
                .collect(Collectors.toList());
        logService.saveAndCheck(this.baseMapper, ApplicationButton::getButtonId, deletedList);
    }

    /**
     * 应用按钮信息
     *
     * @param buttons buttons
     * @return List
     */
    @Override
    public List<ButtonInfoRespDTO> perfectButtonInfo(List<ApplicationButton> buttons) {
        List<Long> buttonIds = StreamUtil.transListT(buttons, ApplicationButton::getButtonId);
        List<Long> creators = StreamUtil.transListT(buttons, ApplicationButton::getCreatorId);
        // 按钮触发条件
        Map<Long, List<JudgeOr>> triggerConditionsMap = applicationJudgeService.findMapBySourceIds(TRIGGER_CONDITION, buttonIds);
        // 按钮规则
        Map<Long, List<RobotRuleDTO>> sourceRulesMap = applicationRobotRuleService.findMapBySourceIds(ROBOT_RULE_TYPE, buttonIds);
        // 按钮筛选条件
        Map<Long, List<JudgeOr>> sourceJudgesMap = applicationJudgeService.findMapBySourceIds(JUDGE_TYPE, buttonIds);
        // 按钮权限
        Map<Long, List<AppPermissionDTO>> appPermissionsMap = applicationPermissionService.findAppPermissionsBySource(APP_PERMISSION_TYPE, buttonIds);
        // 创建人
        Map<Long, UserBaseRespDTO> creatorMap = FindByIdsReqDTO.unFilter(creators).check().map(remoteUserService::findBaseMapByIds).orElse(new HashMap<>());
        return buttons.stream().map(e -> {
            ButtonInfoRespDTO buttonInfoRespDTO = BeanUtil.copyProperties(e, ButtonInfoRespDTO.class);
            // 按钮触发条件
            buttonInfoRespDTO.setTriggerConditions(triggerConditionsMap.getOrDefault(e.getButtonId(), new ArrayList<>()));
            // 按钮规则
            buttonInfoRespDTO.setRobotRules(sourceRulesMap.getOrDefault(e.getButtonId(), new ArrayList<>()));
            // 按钮筛选条件
            buttonInfoRespDTO.setJudgeOrs(sourceJudgesMap.getOrDefault(e.getButtonId(), new ArrayList<>()));
            // 按钮权限
            buttonInfoRespDTO.setPermissions(appPermissionsMap.getOrDefault(e.getButtonId(), new ArrayList<>()));
            // 创建人
            if (creatorMap.containsKey(e.getCreatorId())) {
                buttonInfoRespDTO.setCreator(creatorMap.get(e.getCreatorId()));
            }
            return buttonInfoRespDTO;
        }).collect(Collectors.toList());
    }

    /**
     * 替换按钮信息
     *
     * @param applicationInfo applicationInfo
     * @param controlIdMap    controlIdMap
     * @param isPublish       是否发布
     */
    private void replaceButton(ApplicationInfo applicationInfo, Map<Long, Long> controlIdMap, boolean isPublish) {
        // 发布版
        int releaseVersion = ApplicationVersionEnum.RELEASE_VERSION.getId();
        // 设计版
        int designVersion = ApplicationVersionEnum.DESIGN_VERSION.getId();

        // 查询设计版的按钮列表
        ButtonSourceDTO designSource = new ButtonSourceDTO(ButtonSourceTypeEnum.APPLICATION_BUTTON, applicationInfo.getApplicationId(), designVersion);
        // 查询发布版的按钮列表
        ButtonSourceDTO releaseSource = new ButtonSourceDTO(ButtonSourceTypeEnum.APPLICATION_BUTTON, applicationInfo.getApplicationId(), releaseVersion);

        CopyButtonReqDTO copyButtonReqDTO = new CopyButtonReqDTO();
        copyButtonReqDTO.setUpdateSource(true);
        copyButtonReqDTO.setControlIdMap(controlIdMap);
        if (isPublish) {
            // 发布
            copyButtonReqDTO.setSource(designSource);
            copyButtonReqDTO.setTarget(releaseSource);
        } else {
            // 还原
            copyButtonReqDTO.setSource(releaseSource);
            copyButtonReqDTO.setTarget(designSource);
        }
        // 复制
        this.copyButton(copyButtonReqDTO);
    }

    /**
     * 复制按钮
     *
     * @param source          source 复制源
     * @param targetSource    目标源信息
     * @param targetButtonMap 目标原数据map
     * @param controlIdMap    控件id 替换映射
     * @param updateSource    是否更新源信息
     */
    private void copyButton(ApplicationButton source, ButtonSourceDTO targetSource, Map<Long, ApplicationButton> targetButtonMap, Map<Long, Long> controlIdMap, boolean updateSource) {
        ApplicationButton copy;
        if (targetButtonMap.containsKey(source.getButtonId())) {
            copy = targetButtonMap.get(source.getButtonId());
        } else {
            copy = new ApplicationButton();
            copy.setSourceId(targetSource.getSourceId());
            copy.setSourceType(targetSource.getSourceType());
            copy.setVersion(targetSource.getVersion());
            copy.setEnterpriseId(source.getEnterpriseId());
            copy.setSourceButtonId(source.getButtonId());
        }
        // 复制
        this.copyProp(source, copy, controlIdMap, updateSource);
    }

    /**
     * 复制按钮
     *
     * @param source       复制源
     * @param target       复制目标
     * @param controlIdMap 控件id替换映射
     * @param updateSource 是否更新源信息
     */
    private void copyProp(ApplicationButton source, ApplicationButton target, Map<Long, Long> controlIdMap, boolean updateSource) {
        target.setButtonName(source.getButtonName());
        target.setStyle(source.getStyle());
        target.setTriggerAction(source.getTriggerAction());
        target.setLink(source.getLink());
        target.setTargetApplicationId(source.getTargetApplicationId());
        target.setPermissionStatus(source.getPermissionStatus());
        target.setPasswordStatus(source.getPasswordStatus());
        target.setPassword(source.getPassword());
        target.setRemark(source.getRemark());

        // 更新源信息
        if (updateSource) {
            // ### 更新源信息 证明是应用发布和还原，则按钮key保持一致
            target.setButtonKey(source.getButtonKey());
            target.setSourceButtonId(source.getButtonId());
        }
        logService.saveAndCheck(this.baseMapper, ApplicationButton::getButtonId, target);

        Long sourceId = source.getButtonId();
        Long targetId = target.getButtonId();
        Long enterpriseId = target.getEnterpriseId();
        // 复制 规则
        if (TriggerActionEnum.hasRule(source.getTriggerAction())) {
            applicationRobotRuleService.copyRobotRule(new CopyRobotRuleReqDTO(ROBOT_RULE_TYPE, enterpriseId, sourceId, targetId, controlIdMap, updateSource));
        }
        // 复制 筛选条件
        if (TriggerActionEnum.hasJudge(source.getTriggerAction())) {
            applicationJudgeService.copyJudges(new CopyJudgeReqDTO(JUDGE_TYPE, enterpriseId, sourceId, targetId, controlIdMap, null));
        }
        // 复制 权限
        applicationPermissionService.copyPermission(new CopyAppPermissionReqDTO(APP_PERMISSION_TYPE, enterpriseId, sourceId, targetId, controlIdMap));

        // 更新源信息
        if (updateSource) {
            source.setSourceButtonId(target.getButtonId());
            logService.saveAndCheck(this.baseMapper, ApplicationButton::getButtonId, source);
        }
    }

    /**
     * 保存按钮数据
     *
     * @param button        button
     * @param buttonRespDTO buttonRespDTO
     */
    private void savaButton(ApplicationButton button, ButtonRespDTO buttonRespDTO) {
        buttonRespDTO.copyProp(button);
        logService.saveAndCheck(this.baseMapper, ApplicationButton::getButtonId, button);

        Long enterpriseId = button.getEnterpriseId();
        Long buttonId = button.getButtonId();
        // 保存 触发条件
        applicationJudgeService.saveJudges(new JudgesDTO(TRIGGER_CONDITION, enterpriseId, buttonId, buttonRespDTO.getTriggerConditions()));
        // 保存 规则
        if (TriggerActionEnum.hasRule(button.getTriggerAction())) {
            RobotRulesDTO buttonRuleSourceDTO = new RobotRulesDTO();
            buttonRuleSourceDTO.setEnterpriseId(button.getEnterpriseId());
            buttonRuleSourceDTO.setSourceType(ROBOT_RULE_TYPE.getId());
            buttonRuleSourceDTO.setSourceId(button.getButtonId());
            buttonRuleSourceDTO.setRobotRules(buttonRespDTO.getRobotRules());
            buttonRuleSourceDTO.setTargetApplicationId(button.getTargetApplicationId());
            applicationRobotRuleService.saveRobotRule(buttonRuleSourceDTO);
        }
        // 保存 筛选条件
        if (TriggerActionEnum.hasJudge(button.getTriggerAction())) {
            applicationJudgeService.saveJudges(new JudgesDTO(JUDGE_TYPE, enterpriseId, buttonId, buttonRespDTO.getJudgeOrs()));
        }
        if (PermissionStatusEnum.ASSIGN.getId() == buttonRespDTO.getPermissionStatus()) {
            // 保存 权限
            ModifyAppPermissionReqDTO modifyAppPermissionReqDTO = new ModifyAppPermissionReqDTO();
            modifyAppPermissionReqDTO.setEnterpriseId(button.getEnterpriseId());
            modifyAppPermissionReqDTO.setSourceType(APP_PERMISSION_TYPE.getId());
            modifyAppPermissionReqDTO.setSourceId(button.getButtonId());
            modifyAppPermissionReqDTO.setPermissions(buttonRespDTO.getPermissions());
            applicationPermissionService.modifyPermission(modifyAppPermissionReqDTO);
        }
    }
}
